package com.zxt.content.common.utils;

import com.alibaba.fastjson.JSON;
import com.zxt.content.common.Bean.BUserInfoApiVO;
import com.zxt.content.common.Bean.LoginUserInfoApiVO;
import com.zxt.content.user.constant.UserConstant;
import com.zxt.content.user.utils.UserRedisKey;
import com.zxt.content.user.utils.RedisUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@Component
@Slf4j
public class UserUtil {

    // 令牌自定义标识
    public static String HEADER;

    // 令牌秘钥
    public static String SECRET;

    // 令牌有效期（默认30分钟）
    public static int EXPIRE_TIME;

    @Value("${token.header}")
    public void setHeader(String header) {
        this.HEADER = header;
    }

    @Value("${token.secret}")
    public void setSecret(String secret) {
        this.SECRET = secret;
    }

    @Value("${token.expireTime}")
    public void setExpireTime(int expireTime) {
        this.EXPIRE_TIME = expireTime;
    }

    private static final String LOG_INFO = "user redis ";

    /**
     * 获取登录凭证
     *
     * @return 登录凭证
     */
    public static String getToken() {
        HttpServletRequest request = getCurrentRequest();
        String token = request.getHeader(HEADER);
        if (StringUtils.isNotEmpty(token)) {
            log.info(LOG_INFO + "token from header {}", HEADER);
            return token;
        }
        return null;
    }


    private static HttpServletRequest getCurrentRequest() {
        return RequestContextHolder.currentRequestAttributes() == null ? null : ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
    }

    /**
     * 获取登录用户基本信息
     *
     * @param request
     * @return
     */
    public static BUserInfoApiVO getUser(HttpServletRequest request) {
        BUserInfoApiVO userInfoApiVO = UserContainer.USER_INFO_VO_THREAD_LOCAL.get();
        if (Objects.nonNull(userInfoApiVO)) {
            return userInfoApiVO;
        }
        LoginUserInfoApiVO loginUser = getLoginUser(request);
        if (Objects.isNull(loginUser)) {
            return null;
        }
        return loginUser.getUser();
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public static LoginUserInfoApiVO getLoginUser(HttpServletRequest request) {
        if (Objects.isNull(request)) {
            return null;
        }
        // 获取请求携带的令牌
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token)) {
            Claims claims = parseToken(token);
            // 解析对应的权限以及用户信息
            String uuid = (String) claims.get(UserConstant.LOGIN_USER_KEY);
            String userKey = getToken(uuid);
            Object object = RedisUtils.get(userKey);
            if (Objects.isNull(object)) {
                return null;
            }
            return JSON.parseObject(object.toString(), LoginUserInfoApiVO.class);
        }
        return null;
    }


    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    private static Claims parseToken(String token) {
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
    }

    public static String getToken(String token) {
        return UserRedisKey.getTokenKey(token);
    }

    /**
     * 获取请求token
     *
     * @param request
     * @return token
     */
    private static String getToken(HttpServletRequest request) {
        String token = request.getHeader(HEADER);
        if (StringUtils.isNotEmpty(token) && token.startsWith(UserConstant.TOKEN_PREFIX)) {
            token = token.replace(UserConstant.TOKEN_PREFIX, "");
        }
        return token;
    }


}
